﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vds2465Telegrams;

namespace Vds2465Parser
{
	/// <summary>
	/// This test class verifies that the bytes given in the VdS2465 spec are correctly generated and parsed
	/// </summary>
	[TestClass]	
	public class Generator_FixedBytes_A21_Test
	{
		#region tests

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram01()
		{
			// first generate bytes
			Telegram_Calling_SEND_NDAT telegram = CreateA21_Telegram01();
			
			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x0d, 0x0d, 0x68, 0xF3, 0x01, 0x05, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x56, 0x43, 0x65, 0xFD, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram02()
		{
			// first generate bytes
			Telegram_Returning_CONFIRM_ACK telegram = CreateA21_Telegram02();

			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x09, 0x09, 0x68, 0x00, 0x01, 0x05, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0B, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram03()
		{
			// first generate bytes
			Telegram_Calling_SEND_NDAT telegram = CreateA21_Telegram03();

			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x0d, 0x0d, 0x68, 0xD3, 0x01, 0x05, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x56, 0x43, 0x65, 0xDE, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram04()
		{
			// first generate bytes
			Telegram_Returning_CONFIRM_ACK telegram = CreateA21_Telegram04();

			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x09, 0x09, 0x68, 0x00, 0x01, 0x05, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x0C, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram05()
		{
			// first generate bytes
			Telegram_Calling_SEND_NDAT telegram = CreateA21_Telegram05();

			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x0d, 0x0d, 0x68, 0xF3, 0x01, 0x05, 0x02, 0x00, 0x01, 0x00, 0x01, 0x80, 0x02, 0x56, 0x43, 0x65, 0x7D, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test_A21_Telegram06()
		{
			// first generate bytes
			Telegram_Returning_CONFIRM_ACK telegram = CreateA21_Telegram06();

			IGeneratorParser generatorParser = Helpers.GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegram);

			byte[] expectedBytes = new byte[] { 0x68, 0x09, 0x09, 0x68, 0x00, 0x01, 0x05, 0x03, 0x00, 0x01, 0x00, 0x01, 0x80, 0x8B, 0x16 };
			Assert.IsTrue(Helpers.Equals2ByteArrays(telegramBytes, expectedBytes));

			// second parse the generated bytes
			Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
			Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegram.Equals(telegramParsed));
		}

		#endregion tests

		#region static helpers

		private static Telegram_Calling_SEND_NDAT CreateA21_Telegram01()
		{
			return CreateA21_SendNdat(0x01, true, true);
		}
		
		private static Telegram_Returning_CONFIRM_ACK CreateA21_Telegram02()
		{
			return CreateA21_ConfirmAck(0x01, true);
		}

		private static Telegram_Calling_SEND_NDAT CreateA21_Telegram03()
		{			
			return CreateA21_SendNdat(0x02, false, true);
		}

		private static Telegram_Returning_CONFIRM_ACK CreateA21_Telegram04()
		{
			return CreateA21_ConfirmAck(0x02, true);
		}

		private static Telegram_Calling_SEND_NDAT CreateA21_Telegram05()
		{
			return CreateA21_SendNdat(0x01, true, false);
		}

		private static Telegram_Returning_CONFIRM_ACK CreateA21_Telegram06()
		{
			return CreateA21_ConfirmAck(0x01, false);
		}

		private static Telegram_Calling_SEND_NDAT CreateA21_SendNdat(byte addressUserData02, bool frameCountFlag, bool onOffFlag)
		{
			ReportType_General reportType = new ReportType_General(onOffFlag, eReportSubType_General.Message);
			UserData_02_StatusChangeReport2Confirm userData02 = new UserData_02_StatusChangeReport2Confirm(0x00, addressUserData02, 0x00, eAddressExtension_1.Input, reportType);
			UserDataColl userDataColl = new UserDataColl();
			userDataColl.Add(userData02);
			UserData_56_IdentificationNumber userData56 = new UserData_56_IdentificationNumber("3456");
			userDataColl.Add(userData56);

			Telegram_Calling_SEND_NDAT telegram = new Telegram_Calling_SEND_NDAT(eDirection.ATE_to_RCT, 0x01, true, frameCountFlag, userDataColl);

			return telegram;
		}

		private static Telegram_Returning_CONFIRM_ACK CreateA21_ConfirmAck(byte addressUserData02, bool onOffFlag)
		{
			ReportType_General reportType = new ReportType_General(onOffFlag, eReportSubType_General.Message);
			UserData_03_StatusChangeConfirm userData03 = new UserData_03_StatusChangeConfirm(0x00, addressUserData02, 0x00, eAddressExtension_1.Input, reportType);
			UserDataColl userDataColl = new UserDataColl();
			userDataColl.Add(userData03);

			const byte address = 0x01;
			Telegram_Returning_CONFIRM_ACK telegram = new Telegram_Returning_CONFIRM_ACK(eDirection.RCT_to_ACE, address, false, false, userDataColl);

			return telegram;
		}

		#endregion static helpers
	}
}
